//
//  trooper.m
//  Predator Test
//
//  Created by Tyler Hawkins on 01/02/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#define VISUAL_RANGE 130
#define ATTACK_RANGE 60
#define VISUAL_ANGLE 75		// this is then multiplied by two essentially

#import "Trooper.h"
#import "PredView.h"

@implementation Trooper

- (id) initWithPosition: (CGPoint)thePosition andHealth: (int)theHealth andVectorCenter: (CGPoint)cntrPoint andVectorTerminationPoint: (CGPoint)termPoint andWIdth: (int)wid
{
	self = [super init];
	
	if(self){
		[self setPosition: thePosition];
		[self setHealth: theHealth];
		[self setVetorPointOrigin: cntrPoint andVectorPoint: termPoint];
		[self createRepresentation];
		[self setWidth: wid];
	}
	
	return self;
}

- (id) initWithPosition: (CGPoint) thePosition andHealth: (int) theHealth andAngle: (float) anAngle andWIdth: (int) aWidth andDelegate: (id) dlgt
{
	self = [super init];
	
	if(self){
		[self setPosition: thePosition];
		[self setHealth: theHealth];
		[self setAngle: anAngle];
		[self generateTheOrigin];
		[self generateTheTermpoint];
		[self setWidth: aWidth];
		[self createRepresentation];
		
		myDelegate = dlgt;
	}
	
	return self;
}

- (void) setVisibleArea: (CGPathRef) vsbl
{
	CGPathRelease(visableArea);
	visableArea = CGPathCreateCopy(vsbl);
	CGPathRelease(vsbl);
}

- (CGPathRef) visableArea
{
	return visableArea;
}

- (void) setAttackableArea: (CGPathRef) vsbl
{
	CGPathRelease(attackableArea);
	attackableArea = CGPathCreateCopy(vsbl);
	CGPathRelease(vsbl);
}

- (CGPathRef) attackableArea
{
	return attackableArea;
}

- (void) chooseBehavAction
{
	// BEHAVIOR SELECTOR:
	// 0) Dead/No Movement
	// 1) Hobomode
	// 2) Follow Friend

	[self hoboMode_Behav];
	
	int behaviorSelector = 0;
	
	int whoIsFriend;
	//float distance = 400;
	//int friendDeltaX = VISUAL_RANGE * 2, friendDeltaY = VISUAL_RANGE * 2;
	
	// Analyze Data...
	// FIXME - Follow the closest friend... not just anyone of them!
	bool isFriendIn = 0;
	
	NSMutableArray * troops = [myDelegate troops];
	
	int i;
	for(i = 0 ; (i < [troops count] && isFriendIn != 1) ; i++){
		if([troops objectAtIndex:i] == self){
			continue;
		}
		
		isFriendIn = CGPathContainsPoint([self visableArea], NULL, [[troops objectAtIndex:i] getPosition], 0);
		whoIsFriend = i;
	
	}
//	// Near-by Enemy?
//	// Near-by Friend?
	if(isFriendIn) { 
		behaviorSelector = 2;
	} else {
		behaviorSelector = 1;
	}
	
	// Switch:
	// Hobomode
	// Hold-Attack
	// Persue-Attack
	// Wait/Look around
	
	switch(behaviorSelector){
		case 0:{
			
			//break;
		}
		
		case 1:{
			[self hoboMode_Behav];		
			break;
		}
		
		case 2:{
			
			[self followFriend_Behav: whoIsFriend];
			break;
		}
		
		case 3:{
			//[self setAngle: [self angle] + 0.01];
			break;
		}
	}
	

	
	
	isFriendIn = 0;
}

- (void) followFriend_Behav: (int) friendsIndex
{
	// Move trajectory to point at Friend
	
	if (([self getPosition].x <= 0) || ([self getPosition].x >= 746) || ([self getPosition].y <= 0) || ([self getPosition].y >= 386)){
		[self setAngle: [self angle] + 180];
		[self generateTheTermpoint];
	} else {
	
		NSMutableArray * troops = [myDelegate troops];
		
		float friendX = [[troops objectAtIndex: friendsIndex] getPosition].x;
		float friendY = [[troops objectAtIndex: friendsIndex] getPosition].y;	
		
		friendX -= [self getCenter].x;
		friendY -= [self getCenter].y;
		
		float hypot = sqrt((friendX * friendX) + (friendY * friendY));
		
		float trajectory = friendY / hypot;
		
		[self setAngle: sinh(trajectory)];
		
		[self hoboMode_Behav];
	}
}

- (void) hoboMode_Behav
{
	if (([self getPosition].x <= 0) || ([self getPosition].x >= 746) || ([self getPosition].y <= 0) || ([self getPosition].y >= 386)){
		[self setAngle: [self angle] + 180];
		[self generateTheTermpoint];
	}
	
	[self setPosition: CGPointMake( ([self getPosition].x - (([self getCenter].x - [self terminatingPoint].x) / 10)) , ([self getPosition].y - (([self getCenter].y - [self terminatingPoint].y))/10) )];
	[self generateTheOrigin];
	[self generateTheTermpoint];
	[self createRepresentation];
}

- (void) generateTheOrigin 
{
	float xPos = [self getPosition].x + (width / 2);
	float yPos = [self getPosition].y + (width / 2);
	[self setCenter: CGPointMake(xPos,yPos)];
}

- (void) generateTheTermpoint 
{
	////////////////////////////////
	// Set up movement vector...
	double offsetX = cos([self angle]), offsetY = sin([self angle]);
	offsetX *= 10; offsetY *= 10;
	CGPoint termPoint = CGPointMake( offsetX + [self getCenter].x , offsetY + [self getCenter].y);
	[self setTermpoint: termPoint];
	
	////////////////////////////////
	// Set up this troop's visibleArea...
	float startVis = [self angle] - VISUAL_ANGLE;
	float endVis = [self angle] + VISUAL_ANGLE;
	
	double startVisRayX = (cos(startVis) * VISUAL_RANGE) + [self getCenter].x, startVisRayY = (sin(startVis) * VISUAL_RANGE) + [self getCenter].y;
	double endVisRayX = (cos(endVis) * VISUAL_RANGE) + [self getCenter].x , endVisRayY = (sin(endVis) * VISUAL_RANGE) + [self getCenter].y;

	CGMutablePathRef visPath = CGPathCreateMutable();	
		
	CGPathMoveToPoint(visPath, NULL, [self getCenter].x, [self getCenter].y);
	CGPathAddLineToPoint(visPath, NULL, startVisRayX, startVisRayY);
	CGPathAddLineToPoint(visPath, NULL, endVisRayX, endVisRayY);
	CGPathCloseSubpath(visPath);
	
	[self setVisibleArea: CGPathCreateCopy(visPath)];
	CGPathRelease(visPath);	
	
	////////////////////////////////
	// Set up Troops attackableRange
	double startAttkRayX = (cos(startVis) * ATTACK_RANGE) + [self getCenter].x, startAttkRayY = (sin(startVis) * ATTACK_RANGE) + [self getCenter].y;
	double endAttkRayX = (cos(endVis) * ATTACK_RANGE) + [self getCenter].x , endAttkRayY = (sin(endVis) * ATTACK_RANGE) + [self getCenter].y;

	CGMutablePathRef attkPath = CGPathCreateMutable();	
		
	CGPathMoveToPoint(attkPath, NULL, [self getCenter].x, [self getCenter].y);
	CGPathAddLineToPoint(attkPath, NULL, startAttkRayX, startAttkRayY);
	CGPathAddLineToPoint(attkPath, NULL, endAttkRayX, endAttkRayY);
	CGPathCloseSubpath(attkPath);
	
	[self setAttackableArea: CGPathCreateCopy(attkPath)];
	CGPathRelease(attkPath);

}

- (void) setTermpoint: (CGPoint) trmPt
{
	terminatingPoint = trmPt;
}

- (void) setCenter: (CGPoint) cntr
{
	center = cntr;
}

- (void) setAngle: (float) anAgnle
{
	angle = anAgnle;
}

- (float) angle
{
	return angle;
}

- (void) setWidth: (int) wide
{
	width = wide;
}

- (void) setPosition: (CGPoint) thePosition
{
	position = thePosition;
}

- (void) setHealth: (int) theHealth
{
	health = theHealth;
}

- (void) setVetorPointOrigin: (CGPoint) origin andVectorPoint: (CGPoint) terminationPoint;
{
	center = origin;
	terminatingPoint = terminationPoint;
}

- (CGRect) representation 
{
	return representation;
}

- (void) createRepresentation 
{
	CGRect rep = CGRectMake( position.x, position.y, 20, 20);
	[self setRepresentation: rep];
}

- (void) setRepresentation: (CGRect) theRep
{
	representation = theRep;
}

- (int) width 
{
	return width;
}

- (CGPoint) getPosition
{
	return position;
}

- (int) health
{
	return health;
}

- (CGPoint) getCenter
{
	return center;
}

- (CGPoint) terminatingPoint
{
	return terminatingPoint; 
} 

@end
